Currently the constants are used for two different purpose.
one is for the OPTF hypercall sub command.
another is bit flag for struct opt_feature::mask.
They are different spaces, split them out.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
const struct opt_feature *optf = &d->arch.opt_feature;
struct hvm_hw_ia64_identity_mappings im_save;
- __vmx_identity_mapping_save(optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG4,
+ __vmx_identity_mapping_save(optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG4_FLG,
&optf->im_reg4, &im_save.im_reg4);
- __vmx_identity_mapping_save(optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG5,
+ __vmx_identity_mapping_save(optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG5_FLG,
&optf->im_reg5, &im_save.im_reg5);
- __vmx_identity_mapping_save(optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG7,
+ __vmx_identity_mapping_save(optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG7_FLG,
&optf->im_reg7, &im_save.im_reg7);
return hvm_save_entry(OPT_FEATURE_IDENTITY_MAPPINGS, 0, h, &im_save);
if (!vhpt_enabled(v, vadr, misr.rs ? RSE_REF : DATA_REF)) {
/* windows use region 4 and 5 for identity mapping */
- if ((optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG4) &&
+ if ((optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG4_FLG) &&
REGION_NUMBER(vadr) == 4 && !(regs->cr_ipsr & IA64_PSR_CPL) &&
REGION_OFFSET(vadr) <= _PAGE_PPN_MASK) {
goto try_again;
return IA64_NO_FAULT;
}
- if ((optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG5) &&
+ if ((optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG5_FLG) &&
REGION_NUMBER(vadr) == 5 && !(regs->cr_ipsr & IA64_PSR_CPL) &&
REGION_OFFSET(vadr) <= _PAGE_PPN_MASK) {
}
/* avoid recursively walking (short format) VHPT */
- if (!(optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG4) &&
- !(optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG5) &&
+ if (!(optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG4_FLG) &&
+ !(optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG5_FLG) &&
(((vadr ^ vpta.val) << 3) >> (vpta.size + 3)) == 0) {
goto inject_dtlb_fault;
}
* Helper function for the optimization stuff handling the identity mapping
* feature.
*/
+static inline unsigned long
+optf_identity_mapping_cmd_to_flg(unsigned long cmd)
+{
+ switch(cmd) {
+ case XEN_IA64_OPTF_IDENT_MAP_REG7:
+ return XEN_IA64_OPTF_IDENT_MAP_REG7_FLG;
+ case XEN_IA64_OPTF_IDENT_MAP_REG4:
+ return XEN_IA64_OPTF_IDENT_MAP_REG4_FLG;
+ case XEN_IA64_OPTF_IDENT_MAP_REG5:
+ return XEN_IA64_OPTF_IDENT_MAP_REG5_FLG;
+ default:
+ BUG();
+ return 0;
+ }
+
+ /* NOTREACHED */
+}
+
static inline void
optf_set_identity_mapping(unsigned long* mask, struct identity_mapping* im,
struct xen_ia64_opt_feature* f)
{
+ unsigned long flag = optf_identity_mapping_cmd_to_flg(f->cmd);
+
if (f->on) {
- *mask |= f->cmd;
+ *mask |= flag;
im->pgprot = f->pgprot;
im->key = f->key;
} else {
- *mask &= ~(f->cmd);
+ *mask &= ~flag;
im->pgprot = 0;
im->key = 0;
}
struct opt_feature* optf = &(vcpu->domain->arch.opt_feature);
/* Optimization for identity mapped region 7 OS (linux) */
- if (optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG7 &&
+ if (optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG7_FLG &&
region == 7 && ia64_psr(regs)->cpl == CONFIG_CPL0_EMUL) {
pte.val = address & _PAGE_PPN_MASK;
pte.val = pte.val | optf->im_reg7.pgprot;
unsigned long key; /* A protection key. */
};
+/* opt_feature mask */
+/*
+ * If this feature is switched on, the hypervisor inserts the
+ * tlb entries without calling the guests traphandler.
+ * This is useful in guests using region 7 for identity mapping
+ * like the linux kernel does.
+ */
+#define XEN_IA64_OPTF_IDENT_MAP_REG7_FLG_BIT 0
+#define XEN_IA64_OPTF_IDENT_MAP_REG7_FLG \
+ (1UL << XEN_IA64_OPTF_IDENT_MAP_REG7_FLG_BIT)
+
+/* Identity mapping of region 4 addresses in HVM. */
+#define XEN_IA64_OPTF_IDENT_MAP_REG4_FLG_BIT \
+ (XEN_IA64_OPTF_IDENT_MAP_REG7_FLG_BIT + 1)
+#define XEN_IA64_OPTF_IDENT_MAP_REG4_FLG \
+ (1UL << XEN_IA64_OPTF_IDENT_MAP_REG4_FLG_BIT)
+
+/* Identity mapping of region 5 addresses in HVM. */
+#define XEN_IA64_OPTF_IDENT_MAP_REG5_FLG_BIT \
+ (XEN_IA64_OPTF_IDENT_MAP_REG7_FLG_BIT + 2)
+#define XEN_IA64_OPTF_IDENT_MAP_REG5_FLG \
+ (1UL << XEN_IA64_OPTF_IDENT_MAP_REG5_FLG_BIT)
+
/* Central structure for optimzation features used by the hypervisor. */
struct opt_feature {
unsigned long mask; /* For every feature one bit. */
* This is useful in guests using region 7 for identity mapping
* like the linux kernel does.
*/
-#define XEN_IA64_OPTF_IDENT_MAP_REG7_BIT 0
-#define XEN_IA64_OPTF_IDENT_MAP_REG7 \
- (1UL << XEN_IA64_OPTF_IDENT_MAP_REG7_BIT)
+#define XEN_IA64_OPTF_IDENT_MAP_REG7 1
/* Identity mapping of region 4 addresses in HVM. */
-#define XEN_IA64_OPTF_IDENT_MAP_REG4_BIT \
- (XEN_IA64_OPTF_IDENT_MAP_REG7_BIT + 1)
-#define XEN_IA64_OPTF_IDENT_MAP_REG4 \
- (1UL << XEN_IA64_OPTF_IDENT_MAP_REG4_BIT)
+#define XEN_IA64_OPTF_IDENT_MAP_REG4 2
/* Identity mapping of region 5 addresses in HVM. */
-#define XEN_IA64_OPTF_IDENT_MAP_REG5_BIT \
- (XEN_IA64_OPTF_IDENT_MAP_REG7_BIT + 2)
-#define XEN_IA64_OPTF_IDENT_MAP_REG5 \
- (1UL << XEN_IA64_OPTF_IDENT_MAP_REG5_BIT)
+#define XEN_IA64_OPTF_IDENT_MAP_REG5 3
#define XEN_IA64_OPTF_IDENT_MAP_NOT_SET (0)